home *** CD-ROM | disk | FTP | other *** search
- /* WIDE AREA INFORMATION SERVER SOFTWARE:
- No guarantees or restrictions. See the readme file for the full standard
- disclaimer.
- */
-
- /* Copyright (c) CNIDR (see ../COPYRIGHT) */
-
- #ifndef lint
- static char *RCSid = "$Header: /usr/users/freewais/FreeWAIS-0.1/ir/zutil.c,v 1.1 1993/02/16 15:05:35 freewais Exp $";
- #endif
-
- /* Change log:
- * $Log: zutil.c,v $
- * Revision 1.1 1993/02/16 15:05:35 freewais
- * Initial revision
- *
- * Revision 1.6 92/03/26 18:27:16 jonathan
- * Fixed function declaration.
- *
- * Revision 1.5 92/03/07 19:41:14 jonathan
- * ANSIfied argument list.
- *
- * Revision 1.4 92/02/12 14:01:37 jonathan
- * Added "$Log" so RCS will put the log message in the header
- *
- *
- 3.26.90 Harry Morris, morris@think.com
- 3.30.90 Harry Morris - Changed any->bits to any->bytes
- 4.11.90 HWM - fixed include file names, changed
- - writeCompressedIntegerWithPadding() to
- writeCompressedIntWithPadding()
- - generalized conditional includes (see c-dialect.h)
- 3.7.91 Jonny Goldman. Replaced "short" in makeBitMap with "int" line 632.
- */
-
- #define _C_utils_Z39_50_
-
- #include "zutil.h"
-
- #include <math.h>
- #include <string.h>
-
- char* readErrorPosition = NULL; /* pos where buf stoped making sense */
-
- /*----------------------------------------------------------------------*/
- /* A note on error handling
- read - these are low level routines, they do not check the type tags
- which (sometimes) preceed the data (this is done by the higher
- level functions which call these functions). There is no
- attempt made to check that the reading does not exceed the read
- buffer. Such cases should be very rare and usually will be
- caught by the calling functions. (note - it is unlikely that
- a series of low level reads will go far off the edge without
- triggering a type error. However, it is possible for a single
- bad read in an array function (eg. readAny) to attempt to read a
- large ammount, possibly causing a segmentation violation or out
- of memory condition.
- */
- /*----------------------------------------------------------------------*/
-
- diagnosticRecord*
- makeDiag(surrogate,code,addInfo)
- boolean surrogate;
- char* code;
- char* addInfo;
- {
- diagnosticRecord* diag =
- (diagnosticRecord*)s_malloc((size_t)sizeof(diagnosticRecord));
-
- diag->SURROGATE = surrogate;
- memcpy(diag->DIAG,code,DIAGNOSTIC_CODE_SIZE);
- diag->ADDINFO = s_strdup(addInfo);
-
- return(diag);
- }
-
- /*----------------------------------------------------------------------*/
-
- void
- freeDiag(diag)
- diagnosticRecord* diag;
- {
- if (diag != NULL)
- { if (diag->ADDINFO != NULL)
- s_free(diag->ADDINFO);
- s_free(diag);
- }
- }
-
- /*----------------------------------------------------------------------*/
-
- #define END_OF_RECORD 0x1D
-
- char*
- writeDiag(diag,buffer,len)
- diagnosticRecord* diag;
- char* buffer;
- long* len;
- /* diagnostics (as per Appendix D) have a very weird format - this changes
- in SR-1
- */
- {
- char* buf = buffer;
- long length;
-
- if (diag == NULL) /* handle unspecified optional args */
- return(buf);
-
- buf = writeTag(DT_DatabaseDiagnosticRecords,buf,len);
- CHECK_FOR_SPACE_LEFT(0L,len);
-
- length = 3;
- if (diag->ADDINFO != NULL)
- length += strlen(diag->ADDINFO);
-
- if (length >= 0xFFFF ) /* make sure the length is reasonable */
- { length = 0xFFFF - 1;
- diag->ADDINFO[0xFFFF - 3 - 1] = '\0';
- }
-
- buf = writeBinaryInteger(length,2L,buf,len);
-
- CHECK_FOR_SPACE_LEFT(1L,len);
- buf[0] = diag->DIAG[0];
- buf++;
-
- CHECK_FOR_SPACE_LEFT(1L,len);
- buf[0] = diag->DIAG[1];
- buf++;
-
- if (length > 3)
- { CHECK_FOR_SPACE_LEFT(3L,len);
- memcpy(buf,diag->ADDINFO,(size_t)length - 3);
- buf += length - 3;
- }
-
- CHECK_FOR_SPACE_LEFT(1L,len);
- #ifdef WIN32
- buf[0] = (char)(diag->SURROGATE);
- #else
- buf[0] = diag->SURROGATE;
- #endif
- buf++;
-
- CHECK_FOR_SPACE_LEFT(1L,len);
- buf[0] = END_OF_RECORD;
- buf++;
-
- return(buf);
- }
-
- /*----------------------------------------------------------------------*/
-
- char*
- readDiag(diag,buffer)
- diagnosticRecord** diag;
- char* buffer;
- {
- char* buf = buffer;
- diagnosticRecord* d
- = (diagnosticRecord*)s_malloc((size_t)sizeof(diagnosticRecord));
- data_tag tag;
- long len;
-
- buf = readTag(&tag,buf);
-
- buf = readBinaryInteger(&len,2L,buf);
-
- d->DIAG[0] = buf[0];
- d->DIAG[1] = buf[1];
- d->DIAG[2] = '\0';
-
- if (len > 3)
- { d->ADDINFO = (char*)s_malloc((size_t)(len - 3 + 1));
- memcpy(d->ADDINFO,(char*)(buf + 2),(size_t)(len - 3));
- d->ADDINFO[len - 3] = '\0';
- }
- else
- d->ADDINFO = NULL;
-
- d->SURROGATE = buf[len - 1];
-
- *diag = d;
-
- return(buf + len + 1);
- }
-
- /*----------------------------------------------------------------------*/
-
- #define continueBit 0x80
- #define dataMask 0x7F
- #define dataBits 7
-
- char*
- writeCompressedInteger(num,buf,len)
- unsigned long num;
- char* buf;
- long* len;
- /* write a binary integer in the format described on p. 40.
- this might be sped up
- */
- {
- char byte;
- long i;
- unsigned long size;
-
- size = writtenCompressedIntSize(num);
- #ifdef WIN32
- CHECK_FOR_SPACE_LEFT((long)size,len);
-
- for (i = size - 1; i >= 0; i--)
- { byte = (char)(num & dataMask);
- if (i != (long)(size-1)) /* turn on continue bit */
- #else
- CHECK_FOR_SPACE_LEFT(size,len);
-
- for (i = size - 1; i >= 0; i--)
- { byte = num & dataMask;
- if (i != (size-1)) /* turn on continue bit */
- #endif
- byte = (char)(byte | continueBit);
- buf[i] = byte;
- num = num >> dataBits; /* don't and here */
- }
-
- return(buf + size);
- }
-
- /*----------------------------------------------------------------------*/
-
- char*
- readCompressedInteger(num,buf)
- unsigned long *num;
- char* buf;
- /* read a binary integer in the format described on p. 40.
- this might be sped up
- */
- {
- long i = 0;
- unsigned char byte;
-
- *num = 0;
-
- do
- { byte = buf[i++];
- *num = *num << dataBits;
- *num += (byte & dataMask);
- }
- while (byte & continueBit);
-
- return(buf + i);
- }
-
- /*----------------------------------------------------------------------*/
-
- #define pad 128 /* high bit is set */
-
- char*
- writeCompressedIntWithPadding(num,size,buffer,len)
- unsigned long num;
- unsigned long size;
- char* buffer;
- long* len;
- /* Like writeCompressedInteger, except writes padding (128) to make
- sure that size bytes are used. This can be read correctly by
- readCompressedInteger()
- */
- {
- char* buf = buffer;
- unsigned long needed,padding;
- long i;
-
- #ifdef WIN32
- CHECK_FOR_SPACE_LEFT((long)size,len);
- #else
- CHECK_FOR_SPACE_LEFT(size,len);
- #endif
-
- needed = writtenCompressedIntSize(num);
- padding = size - needed;
- i = padding - 1;
-
- for (i = padding - 1;i >= 0;i--)
- #ifdef WIN32
- { buf[i] = (char)pad;
- #else
- { buf[i] = pad;
- #endif
- }
-
- buf = writeCompressedInteger(num,buf + padding,len);
-
- return(buf);
- }
-
- /*----------------------------------------------------------------------*/
-
- unsigned long
- writtenCompressedIntSize(num)
- unsigned long num;
- /* return the number of bytes needed to represnet the value num in
- compressed format. curently limited to 4 bytes
- */
- {
- if (num < CompressedInt1Byte)
- return(1);
- else if (num < CompressedInt2Byte)
- return(2);
- else if (num < CompressedInt3Byte)
- return(3);
- else
- return(4);
- }
-
- /*----------------------------------------------------------------------*/
-
- char*
- writeTag(tag,buf,len)
- data_tag tag;
- char* buf;
- long* len;
- /* write out a data tag */
- {
- return(writeCompressedInteger(tag,buf,len));
- }
-
- /*----------------------------------------------------------------------*/
-
- char*
- readTag(tag,buf)
- data_tag* tag;
- char* buf;
- /* read a data tag */
- {
- return(readCompressedInteger(tag,buf));
- }
-
- /*----------------------------------------------------------------------*/
-
- unsigned long
- writtenTagSize(tag)
- data_tag tag;
- {
- return(writtenCompressedIntSize(tag));
- }
-
- /*----------------------------------------------------------------------*/
-
- data_tag
- peekTag(buf)
- char* buf;
- /* read a data tag without advancing the buffer */
- {
- data_tag tag;
- readTag(&tag,buf);
- return(tag);
- }
-
- /*----------------------------------------------------------------------*/
-
- any*
- makeAny(size,data)
- unsigned long size;
- char* data;
- {
- any* a = (any*)s_malloc((size_t)sizeof(any));
- a->size = size;
- a->bytes = data;
- return(a);
- }
-
- /*----------------------------------------------------------------------*/
-
- void
- freeAny(a)
- any* a;
- /* destroy an any and its associated data. Assumes a->bytes was
- allocated using the s_malloc family of libraries
- */
- {
- if (a != NULL)
- { if (a->bytes != NULL)
- s_free(a->bytes);
- s_free(a);
- }
- }
-
- /*----------------------------------------------------------------------*/
-
- any*
- duplicateAny(a)
- any* a;
- {
- any* copy = NULL;
-
- if (a == NULL)
- return(NULL);
-
- copy = (any*)s_malloc((size_t)sizeof(any));
- copy->size = a->size;
- if (a->bytes == NULL)
- copy->bytes = NULL;
- else
- { copy->bytes = (char*)s_malloc((size_t)copy->size);
- memcpy(copy->bytes,a->bytes,(size_t)copy->size);
- }
- return(copy);
- }
-
- /*----------------------------------------------------------------------*/
-
- char*
- writeAny(a,tag,buffer,len)
- any* a;
- data_tag tag;
- char* buffer;
- long* len;
- /* write an any + tag and size info */
- {
- char* buf = buffer;
-
- if (a == NULL) /* handle unspecified optional args */
- return(buf);
-
- /* write the tags */
- buf = writeTag(tag,buf,len);
- buf = writeCompressedInteger(a->size,buf,len);
-
- /* write the bytes */
- #ifdef WIN32
- CHECK_FOR_SPACE_LEFT((long)(a->size),len);
- #else
- CHECK_FOR_SPACE_LEFT(a->size,len);
- #endif
- memcpy(buf,a->bytes,(size_t)a->size);
-
- return(buf+a->size);
- }
-
- /*----------------------------------------------------------------------*/
-
- char*
- readAny(anAny,buffer)
- any** anAny;
- char* buffer;
- /* read an any + tag and size info */
- {
- char* buf = buffer;
- any* a = (any*)s_malloc((size_t)sizeof(any));
- data_tag tag;
-
- buf = readTag(&tag,buf);
- buf = readCompressedInteger(&a->size,buf);
- /* now simply copy the bytes */
- a->bytes = (char*)s_malloc((size_t)a->size);
- memcpy(a->bytes,buf,(size_t)a->size);
- *anAny = a;
- return(buf+a->size);
- }
-
- /*----------------------------------------------------------------------*/
-
- unsigned long
- writtenAnySize(tag,a)
- data_tag tag;
- any* a;
- {
- unsigned long size;
-
- if (a == NULL)
- return(0);
-
- size = writtenTagSize(tag);
- size += writtenCompressedIntSize(a->size);
- size += a->size;
- return(size);
- }
-
- /*----------------------------------------------------------------------*/
-
- any*
- stringToAny(s)
- char* s;
- {
- any* a = NULL;
-
- if (s == NULL)
- return(NULL);
-
- a = (any*)s_malloc((size_t)sizeof(any));
- a->size = strlen(s);
- a->bytes = (char*)s_malloc((size_t)a->size);
- memcpy(a->bytes,s,(size_t)a->size);
- return(a);
- }
-
- /*----------------------------------------------------------------------*/
-
- char*
- anyToString(a)
- any* a;
- {
- char* s = NULL;
-
- if (a == NULL)
- return(NULL);
-
- s = s_malloc((size_t)(a->size + 1));
- memcpy(s,a->bytes,(size_t)a->size);
- s[a->size] = '\0';
- return(s);
- }
-
- /*----------------------------------------------------------------------*/
-
- char*
- writeString(s,tag,buffer,len)
- char* s;
- data_tag tag;
- char* buffer;
- long* len;
- /* Write a C style string. The terminating null is not written.
- This function is not part of the Z39.50 spec. It is provided
- for the convienience of those wishing to pass C strings in
- the place of an any.
- */
- {
- char* buf = buffer;
- any* data = NULL;
- if (s == NULL)
- return(buffer); /* handle unused optional item before making an any */
- data = (any*)s_malloc((size_t)sizeof(any));
- data->size = strlen(s);
- data->bytes = s; /* save a copy here by not using stringToAny() */
- buf = writeAny(data,tag,buf,len);
- s_free(data); /* don't use freeAny() since it will free s too */
- return(buf);
- }
-
- /*----------------------------------------------------------------------*/
-
- char*
- readString(s ,buffer)
- char** s ;
- char* buffer;
- /* Read an any and convert it into a C style string.
- This function is not part of the Z39.50 spec. It is provided
- for the convienience of those wishing to pass C strings in
- the place of an any.
- */
- {
- any* data = NULL;
- char* buf = readAny(&data,buffer);
- *s = anyToString(data);
- freeAny(data);
- return(buf);
- }
-
- /*----------------------------------------------------------------------*/
-
- unsigned long
- writtenStringSize(tag,s)
- data_tag tag;
- char* s;
- {
- unsigned long size;
-
- if (s == NULL)
- return(0);
-
- size = writtenTagSize(tag);
- size += writtenCompressedIntSize(size);
- size += strlen(s);
- return(size);
- }
-
- /*----------------------------------------------------------------------*/
-
- any*
- longToAny(num)
- long num;
- /* a convienience function */
- {
- char s[40];
-
- sprintf(s,"%ld",num);
-
- return(stringToAny(s));
- }
-
- /*----------------------------------------------------------------------*/
-
- long
- anyToLong(a)
- any* a;
- /* a convienience function */
- {
- long num;
- char* str = NULL;
- str = anyToString(a);
- sscanf(str,"%ld",&num); /* could check the result and return
- an error */
- s_free(str);
- return(num);
- }
-
- /*----------------------------------------------------------------------*/
-
- #define bitsPerByte 8
-
- #ifdef ANSI_LIKE /* use ansi */
-
- bit_map*
- makeBitMap(unsigned long numBits,...)
- /* construct and return a bitmap with numBits elements */
- {
- va_list ap;
- long i,j;
- bit_map* bm = NULL;
-
- va_start(ap,numBits);
-
- bm = (bit_map*)s_malloc((size_t)sizeof(bit_map));
- bm->size = (unsigned long)ceil((double)numBits / bitsPerByte);
- bm->bytes = (char*)s_malloc((size_t)bm->size);
-
- /* fill up the bits */
- #ifdef WIN32
- for (i = 0; i < (long)(bm->size); i++) /* iterate over bytes */
- #else
- for (i = 0; i < bm->size; i++) /* iterate over bytes */
- #endif
- { char byte = 0;
- for (j = 0; j < bitsPerByte; j++) /* iterate over bits */
- #ifdef WIN32
- { if ((i * bitsPerByte + j) < (long)numBits)
- #else
- { if ((i * bitsPerByte + j) < numBits)
- #endif
- { boolean bit = false;
- bit = (boolean)va_arg(ap,boolean);
- if (bit)
- { byte = byte | (1 << (bitsPerByte - j - 1));
- }
- }
- }
- bm->bytes[i] = byte;
- }
-
- va_end(ap);
- return(bm);
- }
-
- #else /* use K & R */
-
- bit_map*
- makeBitMap(va_alist)
- va_dcl
- /* construct and return a bitmap with numBits elements */
- {
- va_list ap;
- long i,j;
- unsigned long numBits;
- bit_map* bm = (bit_map*)s_malloc((size_t)sizeof(bit_map));
-
- va_start(ap);
-
- numBits = va_arg(ap,unsigned long);
-
- bm->size = (unsigned long)ceil((double)numBits / bitsPerByte);
-
- bm->bytes = (char*)s_malloc((size_t)bm->size);
-
- /* fill up the bits */
- for (i = 0; i < bm->size; i++) /* iterate over bytes */
- { char byte = 0;
- for (j = 0; j < bitsPerByte; j++) /* iterate over bits */
- { if ((i * bitsPerByte + j) < numBits)
- { boolean bit;
- bit = (boolean)va_arg(ap,int); /* really boolean, but this
- is how it is passed on stack */
- if (bit)
- { byte = byte | (1 << (bitsPerByte - j - 1));
- }
- }
- }
- bm->bytes[i] = byte;
- }
-
- va_end(ap);
-
- return(bm);
- }
-
- #endif
-
- /*----------------------------------------------------------------------*/
-
- void
- freeBitMap(bm)
- bit_map* bm;
- /* destroy a bit map created by makeBitMap() */
- {
- s_free(bm->bytes);
- s_free(bm);
- }
-
- /*----------------------------------------------------------------------*/
-
- /* use this routine to interpret a bit map. pos specifies the bit
- number. bit 0 is the Leftmost bit of the first byte.
- Could do bounds checking.
- */
-
- boolean
- bitAtPos(pos,bm)
- long pos;
- bit_map* bm;
- {
- #ifdef WIN32
- if (pos > (long)(bm->size*bitsPerByte))
- #else
- if (pos > bm->size*bitsPerByte)
- #endif
- return false;
- else
- return((bm->bytes[(pos / bitsPerByte)] &
- (0x80>>(pos % bitsPerByte))) ?
- true : false);
- }
-
- /*----------------------------------------------------------------------*/
-
- char*
- writeBitMap(bm,tag,buffer,len)
- bit_map* bm;
- data_tag tag;
- char* buffer;
- long* len;
- /* write a bitmap + type and size info */
- {
- return(writeAny((any*)bm,tag,buffer,len));
- }
-
- /*----------------------------------------------------------------------*/
-
- char*
- readBitMap(bm,buffer)
- bit_map** bm;
- char* buffer;
- /* read a bitmap + type and size info */
- {
- return(readAny((any**)bm,buffer));
- }
-
- /*----------------------------------------------------------------------*/
-
- char*
- writeByte(byte,buf,len)
- unsigned long byte;
- char* buf;
- long* len;
- {
- CHECK_FOR_SPACE_LEFT(1L,len);
- #ifdef WIN32
- buf[0] = (char)(byte & 0xFF); /* we really only want the first byte */
- #else
- buf[0] = byte & 0xFF; /* we really only want the first byte */
- #endif
- return(buf + 1);
- }
-
- /*----------------------------------------------------------------------*/
-
- char*
- readByte(byte,buf)
- unsigned char* byte;
- char* buf;
- {
- *byte = buf[0];
- return(buf + 1);
- }
-
- /*----------------------------------------------------------------------*/
-
- char*
- writeBoolean(flag,buf,len)
- boolean flag;
- char* buf;
- long* len;
- {
- return(writeByte(flag,buf,len));
- }
-
- /*----------------------------------------------------------------------*/
-
- char*
- readBoolean(flag,buffer)
- boolean* flag;
- char* buffer;
- {
- unsigned char byte;
- char* buf = readByte(&byte,buffer);
- *flag = (byte == true) ? true : false;
- return(buf);
- }
-
- /*----------------------------------------------------------------------*/
-
- char*
- writePDUType(pduType,buf,len)
- pdu_type pduType;
- char* buf;
- long* len;
- /* PDUType is a single byte */
- {
- return(writeBinaryInteger((long)pduType,(unsigned long)1,buf,len));
- }
-
- /*----------------------------------------------------------------------*/
-
- char*
- readPDUType(pduType,buf)
- pdu_type* pduType;
- char* buf;
- /* PDUType is a single byte */
- {
- return(readBinaryInteger((long*)pduType,(unsigned long)1,buf));
- }
-
- /*----------------------------------------------------------------------*/
-
- pdu_type
- peekPDUType(buf)
- char* buf;
- /* read the next pdu without advancing the buffer, Note that this
- function is to be used on a buffer that is known to contain an
- APDU. The pdu_type is written HEADER_LEN bytes into the buffer
- */
- {
- pdu_type pdu;
- readPDUType(&pdu,buf + HEADER_LEN);
- return(pdu);
- }
-
- /*----------------------------------------------------------------------*/
-
- #define BINARY_INTEGER_BYTES sizeof(long) /* the number of bytes used by
- a "binary integer" */
- char*
- writeBinaryInteger(num,size,buf,len)
- long num;
- unsigned long size;
- char* buf;
- long* len;
- /* write out first size bytes of num - no type info
- XXX should this take unsigned longs instead ??? */
- {
- long i;
- char byte;
-
- if (size < 1 || size > BINARY_INTEGER_BYTES)
- return(NULL); /* error */
-
- #ifdef WIN32
- CHECK_FOR_SPACE_LEFT((long)size,len);
- #else
- CHECK_FOR_SPACE_LEFT(size,len);
- #endif
-
- for (i = size - 1; i >= 0; i--)
- { byte = (char)(num & 255);
- buf[i] = byte;
- num = num >> bitsPerByte; /* don't and here */
- }
-
- return(buf + size);
- }
-
- /*----------------------------------------------------------------------*/
-
- char*
- readBinaryInteger(num,size,buf)
- long* num;
- unsigned long size;
- char* buf;
- /* read in first size bytes of num - no type info
- XXX this should take unsigned longs instead !!! */
- {
- long i;
- unsigned char byte;
- if (size < 1 || size > BINARY_INTEGER_BYTES)
- return(buf); /* error */
- *num = 0;
- #ifdef WIN32
- for (i = 0; i < (long)size; i++)
- #else
- for (i = 0; i < size; i++)
- #endif
- { byte = buf[i];
- *num = *num << bitsPerByte;
- *num += byte;
- }
- return(buf + size);
- }
-
- /*----------------------------------------------------------------------*/
-
- unsigned long
- writtenCompressedBinIntSize(num)
- long num;
- /* return the number of bytes needed to represent the value num.
- currently limited to max of 4 bytes
- Only compresses for positive nums - negatives get whole 4 bytes
- */
- {
- if (num < 0L)
- return(4);
- else if (num < 256L) /* 2**8 */
- return(1);
- else if (num < 65536L) /* 2**16 */
- return(2);
- else if (num < 16777216L) /* 2**24 */
- return(3);
- else
- return(4);
- }
-
- /*----------------------------------------------------------------------*/
-
- char*
- writeNum(num,tag,buffer,len)
- long num;
- data_tag tag;
- char* buffer;
- long* len;
- /* write a binary integer + size and tag info */
- {
- char* buf = buffer;
- long size = writtenCompressedBinIntSize(num);
-
- if (num == UNUSED)
- return(buffer);
-
- buf = writeTag(tag,buf,len);
- buf = writeCompressedInteger(size,buf,len);
- buf = writeBinaryInteger(num,(unsigned long)size,buf,len);
- return(buf);
- }
-
- /*----------------------------------------------------------------------*/
-
- char*
- readNum(num,buffer)
- long* num;
- char* buffer;
- /* read a binary integer + size and tag info */
- {
- char* buf = buffer;
- data_tag tag;
- unsigned long size;
- unsigned long val;
-
- buf = readTag(&tag,buf);
- buf = readCompressedInteger(&val,buf);
- size = (unsigned long)val;
- buf = readBinaryInteger(num,size,buf);
- return(buf);
- }
-
- /*----------------------------------------------------------------------*/
-
- unsigned long
- writtenNumSize(tag,num)
- data_tag tag;
- long num;
- {
- long dataSize = writtenCompressedBinIntSize(num);
- long size;
-
- size = writtenTagSize(tag); /* space for the tag */
- size += writtenCompressedIntSize(dataSize); /* space for the size */
- size += dataSize; /* space for the data */
-
- return(size);
- }
-
- /*----------------------------------------------------------------------*/
-
- typedef void (voidfunc)();
-
- void
- doList(list,func)
- void** list;
- voidfunc *func;
- /* call func on each element of the NULL terminated list of pointers */
- {
- register long i;
- register void* ptr = NULL;
- if (list == NULL)
- return;
- for (i = 0,ptr = list[i]; ptr != NULL; ptr = list[++i])
- (*func)(ptr);
- }
-
- /*----------------------------------------------------------------------*/
-
- char*
- writeProtocolVersion(buf,len)
- char* buf;
- long* len;
- /* write a bitmap describing the protocols available */
- {
- static bit_map* version = NULL;
-
- if (version == NULL)
- { version = makeBitMap((unsigned long)1,true); /* version 1! */
- }
-
- return(writeBitMap(version,DT_ProtocolVersion,buf,len));
- }
-
- /*----------------------------------------------------------------------*/
-
- char*
- defaultImplementationID()
- {
- static char ImplementationID[] = "TMC";
- return(ImplementationID);
- }
-
- /*----------------------------------------------------------------------*/
-
- char*
- defaultImplementationName()
- {
- static char ImplementationName[] = "Thinking Machines Corporation Z39.50";
- return(ImplementationName);
- }
-
- /*----------------------------------------------------------------------*/
-
- char*
- defaultImplementationVersion()
- {
- static char ImplementationVersion[] = "2.0A";
- return(ImplementationVersion);
- }
-
- /*----------------------------------------------------------------------*/
-
-